package com.icss.train_sys_back.service.home.impl;

import com.icss.train_sys_back.entity.ResponseResult;
import com.icss.train_sys_back.entity.ResultEnum;
import com.icss.train_sys_back.entity.home.*;
import com.icss.train_sys_back.entity.ticket_manage.ChangeTicketEntity;
import com.icss.train_sys_back.entity.ticket_manage.TicketEntity;
import com.icss.train_sys_back.mapper.home.OrderMapper;
import com.icss.train_sys_back.mapper.ticket_manage.ChangeTicketMapper;
import com.icss.train_sys_back.mapper.ticket_manage.TicketManageMapper;
import com.icss.train_sys_back.mapper.train_manage.TrainNumberMapper;
import com.icss.train_sys_back.service.home.OrderService;
import com.icss.train_sys_back.service.system_service.UserService;
import com.icss.train_sys_back.utils.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import com.icss.train_sys_back.entity.order.OrderMessage;
import com.icss.train_sys_back.config.RabbitMQConfig;

/**
 * @Author 小泽
 * @createTime 2025/10/13 10:34
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private TrainNumberMapper trainNumberMapper;
    @Autowired
    private TicketManageMapper ticketManageMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserService userService;
    @Autowired
    private ChangeTicketMapper changeTicketMapper;

    //创建订单（插入order_passenger 表  和 order 表）

    //创建一个插入order_passenger 的对应实体类
    //插入两表
    //createOrder = CreateOrderDTO(userId=29, ticketId=T202510136571, price=382.56, passengerIds=[1, 2])
    @Override
    @Transactional
    public synchronized ResponseResult createOrder(CreateOrderDTO createOrder) {
        //验证是否重复购票 -- 查order_passenger表是否有该 passengerIds里的记录
        List<OrderPassengerEntity> orderPassengerEntityList = orderMapper.checkIsRepeatBuyTicket(createOrder);
        if (!orderPassengerEntityList.isEmpty()) {
            log.info("重复购票 list = {}", orderPassengerEntityList);
            //重复购票
            return ResponseResult.fail(ResultEnum.REPEAT_BUY);
        }
        OrderEntity order = new OrderEntity();

        //1.创建订单号  （雪花算法）
        SnowflakeIdWorker IdWorker = new SnowflakeIdWorker();
        String orderNumber = String.valueOf(IdWorker.nextId());

        //车票数量减少
        ticketManageMapper.updateTicketNumber(createOrder.getTicketId(), createOrder.getPassengerIds().size());

        //2.查询所购买车票对应车次上的座位，根据车票查车次，再根据车次查车辆，再根据车辆查看座位
        List<Integer> hasSeat = orderMapper.querySeat(createOrder.getTicketId(), createOrder.getPassengerIds().size());
        if (hasSeat.size() == createOrder.getPassengerIds().size()) {
            //修改查到座位的状态为 2 - 锁定
            orderMapper.updateSeatStatus(hasSeat);
        } else {
            return ResponseResult.fail(ResultEnum.TICKET_NUMBER_ERROR);
        }
        //2.1 根据座位id 和 车辆train_number，减少车厢里座位数
        //车票表里的车次train_number_id 查到 train_number 车辆号
        Integer train_number_id = ticketManageMapper.getTicketsByTicketId(createOrder.getTicketId());
        String trainNumber = trainNumberMapper.findTrainNumberByTrainId(train_number_id).getTrainNumber();

        //3.向订单表中插入数据
        order.setOrderId(orderNumber);
        order.setUserId(createOrder.getUserId());
        order.setTicketId(createOrder.getTicketId());
        order.setOrderPrice(createOrder.getPrice()
                .multiply(BigDecimal.valueOf(createOrder.getPassengerIds().size())));
        orderMapper.addOrder(order);

        //4.向order_passenger表中添加数据
        // 构建批量插入数据
        List<OrderPassengerDTO> orderPassengers = new ArrayList<>();
        for (int i = 0; i < createOrder.getPassengerIds().size(); i++) {
            OrderPassengerDTO dto = new OrderPassengerDTO();
            dto.setOrderId(orderNumber);
            dto.setPassengerId(createOrder.getPassengerIds().get(i));
            dto.setSeatId(hasSeat.get(i));
            orderPassengers.add(dto);
        }

        // 批量插入
        orderMapper.batchInsertOrderPassenger(orderPassengers);

        // 构建订单消息并发送到RabbitMQ
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderId(Long.valueOf(orderNumber));
        orderMessage.setUserId(Long.valueOf(createOrder.getUserId()));
        orderMessage.setTrainNumber(trainNumber);
        orderMessage.setTotalAmount(order.getOrderPrice());
        rabbitTemplate.convertAndSend(RabbitMQConfig.ORDER_QUEUE, orderMessage);

        return ResponseResult.success(orderNumber);

    }

    //获取订单信息
    @Override
    public OrderEntity getOrderInfo(String orderId) {
        OrderEntity orderInfo = orderMapper.getOrderInfo(orderId);
        if (orderInfo.getOrderStatus() == 2) {
            return null;
        }
        return orderInfo;
    }

    //取消订单
    @Override
    @Transactional
    public boolean cancelOrder(String orderId) {
        log.info("进入第一步  取消订单   orderId = {}",orderId);
        //若该订单状态已经为 2 --取消 则直接返回
        boolean flag = orderMapper.getOrderInfo(orderId).getOrderStatus() == 2;
        if (flag) {
            return true;
        }

        int res = 0;
        //根据订单号查到order_passenger里的数据
        List<OrderPassengerEntity> orderPassengerEntityList = orderMapper.findOrderPassengerListByOrderId(orderId);

        List<Integer> seatIds = new ArrayList<>();
        for (OrderPassengerEntity orderPassenger : orderPassengerEntityList) {
            //order_passenger表的数据中拿到seat_id
            Integer seatId = orderPassenger.getSeatId();
            seatIds.add(seatId);
            //根据seat_id查seat表 ，获取到座位号对应的车辆号和车厢号
            Map<String, Object> trainAndCarriage;
            trainAndCarriage = orderMapper.findTrainAndCarriageBySeatId(seatId);
            String train_number = (String) trainAndCarriage.get("train_number");
            Integer carriageNumber = null;

            Object carriageNumberObj = trainAndCarriage.get("carriage_number");
            if (carriageNumberObj instanceof Integer) {
                carriageNumber = (Integer) carriageNumberObj;
            } else if (carriageNumberObj instanceof String) {
                carriageNumber = Integer.valueOf((String) carriageNumberObj);
            }
            //根据车辆号 和 车厢号 ，将train_carriage 表中 车厢号的座位数量+1
            res = orderMapper.updateCarriageSeatCountByCarriageAndTrainNumber(carriageNumber, train_number);

        }
        //座位状态恢复为0
        orderMapper.updateSeatStatusCancel(seatIds);

        //删除order_passenger表的数据
        orderMapper.deleteOrderPassengerRecordsByOrderId(orderId);

        //更新order表状态为已取消
        orderMapper.updateOrderStatus(orderId, 2);

        return res == 0;
    }

    //改签车次查询  startStationId = 3，endStationId = 15，date = 2025-11-19，timeRange = 06:00-12:00
    @Override
    @Transactional
    public List<TicketEntity> getNewTrainTickets(Integer startStationId, Integer endStationId, String date, String timeRange) {
        LocalDate dateTime = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return orderMapper.getNewTrainTickets(startStationId, endStationId, dateTime);
    }

    //改签请求
    //ChangeTicketEntity(changeId=, ticketId=T202511192180, orderId=1440758857864314880,
    // userId=28, username=,originalTrainNumber=172, newTrainNumber=116,
    // startStation=广州南站, endStation=哈尔滨西站,
    // originalPrice=1290.64, newPrice=1390.64, changeFee=0, applyTime=2025-11-20T01:22:33.386,
    // processTime=null, status=0, processBy=, reason=改签申请：从 车次172 改签为 116,
    // remark=用户申请改签，原票车次172改签为116,
    // newTicketId=T1440398336405274645)
    @Override
    public ResponseResult changeTicket(Integer userId, ChangeTicketEntity changeTicket) {
        log.info("改签请求开始====================");
        //1.退原先的票  -- 根据orderId
        cancelOrder(changeTicket.getOrderId());

        //2.改签记录表插入数据  changeId  username  changeFee
        log.info("进入第二部   插入改签记录  ");
        SnowflakeIdWorker worker = new SnowflakeIdWorker();
        long changeId = worker.nextId();
        changeTicket.setChangeId(String.valueOf(changeId));
        String username = userService.checkLogin(changeTicket.getUserId()).getUsername();
        changeTicket.setUsername(username);
        changeTicket.setChangeFee(BigDecimal.valueOf(88));
        changeTicketMapper.addRecord(changeTicket);
        //3.下单新的票  -- 根据newTicketId
        ResponseResult<Object> result = buyNewTicket(changeTicket);
        log.info("改签完成=====================");
        return result;
    }

    public ResponseResult<Object> buyNewTicket(ChangeTicketEntity changeTicket) {
        log.info("进入第三步 购买新的票  newTicketId = {}",changeTicket.getNewTicketId());
        OrderEntity order = new OrderEntity();

        //1.创建订单号  （雪花算法）
        SnowflakeIdWorker IdWorker = new SnowflakeIdWorker();
        String orderNumber = String.valueOf(IdWorker.nextId());

        //车票数量减少
        List<Integer> passengerIds = new ArrayList<>();
        PassengerEntity passenger = userService.getPassengerByUserId(changeTicket.getUserId());

        passengerIds.add(passenger.getPassengerId());
        ticketManageMapper.updateTicketNumber(changeTicket.getNewTicketId(), passengerIds.size());

        //2.查询所购买车票对应车次上的座位，根据车票查车次，再根据车次查车辆，再根据车辆查看座位
        List<Integer> hasSeat = orderMapper.querySeat(changeTicket.getNewTicketId(), passengerIds.size());
        if (hasSeat.size() == passengerIds.size()) {
            //修改查到座位的状态为 2 - 锁定
            orderMapper.updateSeatStatus(hasSeat);
        } else {
            return ResponseResult.fail(ResultEnum.TICKET_NUMBER_ERROR);
        }
        //2.1 根据座位id 和 车辆train_number，减少车厢里座位数
        //车票表里的车次train_number_id 查到 train_number 车辆号
        Integer train_number_id = ticketManageMapper.getTicketsByTicketId(changeTicket.getNewTicketId());
        String trainNumber = trainNumberMapper.findTrainNumberByTrainId(train_number_id).getTrainNumber();

        //3.向订单表中插入数据
        order.setOrderId(orderNumber);
        order.setUserId(changeTicket.getUserId());
        order.setTicketId(changeTicket.getNewTicketId());
        order.setOrderPrice(changeTicket.getNewPrice()
                .multiply(BigDecimal.valueOf(passengerIds.size())));
        orderMapper.addOrder(order);

        //4.向order_passenger表中添加数据
        // 构建批量插入数据
        List<OrderPassengerDTO> orderPassengers = new ArrayList<>();
        for (int i = 0; i < passengerIds.size(); i++) {
            OrderPassengerDTO dto = new OrderPassengerDTO();
            dto.setOrderId(orderNumber);
            dto.setPassengerId(passengerIds.get(i));
            dto.setSeatId(hasSeat.get(i));
            orderPassengers.add(dto);
        }

        // 批量插入
        orderMapper.batchInsertOrderPassenger(orderPassengers);

        // 构建订单消息并发送到RabbitMQ
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setOrderId(Long.valueOf(orderNumber));
        orderMessage.setUserId(Long.valueOf(changeTicket.getUserId()));
        orderMessage.setTrainNumber(trainNumber);
        orderMessage.setTotalAmount(order.getOrderPrice());
        rabbitTemplate.convertAndSend(RabbitMQConfig.ORDER_QUEUE, orderMessage);

        return ResponseResult.success(orderNumber);
    }
}
